package hibernate.util;

import freemarker.template.Configuration;
import freemarker.template.Template;
import util.StringUtil;

import java.io.*;
import java.util.*;


/**
 * 代码生成工具
 * 
 * 主要用来通过model类生成dao、daoImpl、service、serviceImpl、controller文件
 * 

 * 
 * @author tianwei.zhou
 *
 */
public class GeneratorUtil {

	/**
	 * 测试方法
	 * 
	 * @param args
	 * @throws java.io.IOException
	 */
    private static final String BASE_DIR="F:\\openCode\\openCode-demo\\src\\main\\java\\hibernate\\model";
    private static final String TO_DIR="F:\\openCode\\openCode-demo\\src\\main\\java\\hibernate";
    private static final String DAO_PACKAGE="sy.dao.demo";
    private static final String SERVICE_PACKAGE="sy.service.demo";
    private static final String AUTHOR="tianwei.zhou";
    private static final String DAO_IMPL_PACKAGE=DAO_PACKAGE+".impl";
    private static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl";
    private static final String DAO_PATH = TO_DIR + "/" + DAO_PACKAGE.replaceAll("\\.", "/");
    private static final String DAO_IMPL_PATH = TO_DIR + "/" + DAO_IMPL_PACKAGE.replaceAll("\\.", "/");
    private static final String SERVICE_PATH = TO_DIR + "/" + SERVICE_PACKAGE.replaceAll("\\.", "/");
    private static final String SERVICE_IMPL_PATH = TO_DIR + "/" + SERVICE_IMPL_PACKAGE.replaceAll("\\.", "/");

	public static void main(String[] args) throws IOException {
		GeneratorUtil generatorUtil = new GeneratorUtil();
		Boolean b = generatorUtil.generator();
		if (b) {
			System.out.println("生成完毕");
		} else {
			System.out.println("第二个参数有问题，不存在的目录？");
		}
	}

	private String pkType = "Long";// 主键类型


    public GeneratorUtil() {
    }


	/**
	 * 通过model类生成dao、daoImpl、service、serviceImpl、controller文件
	 * 
	 * @throws java.io.IOException
	 */
	synchronized public Boolean generator() throws IOException {

		return generator(null);

	}

	/**
	 * 通过model类生成dao、daoImpl、service、serviceImpl、controller文件
	 * 
	 * @param modelNames
	 *            要通过哪些model生成
	 * @return
	 * @throws java.io.IOException
	 */
	synchronized public Boolean generator(String[] modelNames) throws IOException {

		System.out.println("准备在【" + TO_DIR + "】生成文件");
		System.out.println("Model文件路径【" + BASE_DIR + "】");
		System.out.println("主键类型【" + pkType + "】");
		System.out.println("预计生成DAO的包名【" + DAO_PACKAGE + "】");
		System.out.println("预计在【" + DAO_PATH + "】生成dao接口文件");
		System.out.println("预计生成DAOImpl的包名【" + DAO_IMPL_PACKAGE + "】");
		System.out.println("预计在【" + DAO_IMPL_PATH + "】生成daoImpl类文件");
		System.out.println("预计生成service的包名【" + SERVICE_PACKAGE + "】");
		System.out.println("预计在【" + SERVICE_PATH + "】生成service接口文件");
		System.out.println("预计生成serviceImpl的包名【" + SERVICE_IMPL_PACKAGE + "】");
		System.out.println("预计在【" + SERVICE_IMPL_PATH + "】生成serviceImpl类文件");
		System.out.println("------------------------------------------------------------------------------------------");

		File file = new File(BASE_DIR);
		File[] modelFiles = file.listFiles();// model文件数组

		if (modelFiles != null) {

			List<File> modelFileList = Arrays.asList(modelFiles);
			List<File> generatorFileList = new ArrayList<File>();

			if (modelNames != null && modelNames.length > 0) {// 如果要指定某些model来生成dao、service、controller文件
				for (File modelFile : modelFileList) {
					for (String mn : modelNames) {
						if (modelFile.getName().equalsIgnoreCase(mn + ".java")) {
							generatorFileList.add(modelFile);
						}
					}
				}
				modelFileList = generatorFileList;
			}

			generatorDao(modelFileList);


		}

		if (modelFiles == null) {
			return false;
		}
		return true;

	}

	private void generatorDao(List<File> modelFileList) throws IOException {
        Configuration freemarkerCfg = new Configuration();
        freemarkerCfg.setClassForTemplateLoading(GeneratorUtil.class, "/");
        freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8");
        Template template = freemarkerCfg.getTemplate("template/dao.ftl");
        template.setEncoding("UTF-8");

		System.out.println("准备生成DAO接口......");
		File path = new File(DAO_PATH);
		path.mkdirs();
        try{
            for (File modelFile : modelFileList) {
                if (modelFile.getName().lastIndexOf(".java") > -1) {
                    Map<String, String> bindingMap = getBindingMap(modelFile);

                    FileOutputStream fileOutputStream = new FileOutputStream(DAO_PATH + "/" + bindingMap.get("modelName") + "Dao.java");// 生成DAO接口文件
                    Writer out = new BufferedWriter(new OutputStreamWriter(fileOutputStream, "UTF-8"));
                    template.process(bindingMap,out);
                    out.flush();
                    System.out.println("生成【" + bindingMap.get("modelName") + "Dao.java】");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

		System.out.println("所有DAO接口生成完毕！");
		System.out.println("------------------------------------------------------------------------------------------");
	}

	private Map<String, String> getBindingMap(File modelFile) throws IOException {
		FileInputStream fis = new FileInputStream(modelFile);
		InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
		BufferedReader br = new BufferedReader(isr);
		String firstString = br.readLine();
		String modelPackageName = firstString.replace("package ", "").replace(";", "").trim();// model的包名
		br.close();
		isr.close();
		fis.close();
		String modelName = modelFile.getName().substring(0, modelFile.getName().indexOf("."));// model的名字
		Map<String, String> bindingMap = new HashMap<String, String>();
		bindingMap.put("modelPackageName", modelPackageName);
		bindingMap.put("pkType", pkType);
		bindingMap.put("modelName", modelName);
		bindingMap.put("lowerModelName", StringUtil.lowerFirst(modelName));
		bindingMap.put("daoPackageName", DAO_PACKAGE);
		bindingMap.put("daoImplPackageName", DAO_IMPL_PACKAGE);
		bindingMap.put("servicePackageName", SERVICE_PACKAGE);
		bindingMap.put("serviceImplPackageName", SERVICE_IMPL_PACKAGE);
        bindingMap.put("author",AUTHOR);
        bindingMap.put("date",new Date().toString());
		return bindingMap;
	}

}
